/**
 * 可访问性测试工具 - 适老化版本
 * 专门针对老年人使用场景的可访问性测试
 */

class AccessibilityTester {
  constructor() {
    this.testResults = {
      colorContrast: [],
      touchTargets: [],
      fontSizes: [],
      navigation: [],
      voiceSupport: [],
      overall: null
    }
    this.warnings = []
    this.errors = []
  }

  // 运行所有可访问性测试
  async runAllTests() {
    console.log('[可访问性测试] 开始运行适老化可访问性测试...')
    
    this.testResults = {
      colorContrast: [],
      touchTargets: [],
      fontSizes: [],
      navigation: [],
      voiceSupport: [],
      overall: null
    }
    this.warnings = []
    this.errors = []

    try {
      // 测试颜色对比度
      await this.testColorContrast()
      
      // 测试触摸目标大小
      await this.testTouchTargets()
      
      // 测试字体大小
      await this.testFontSizes()
      
      // 测试导航可访问性
      await this.testNavigation()
      
      // 测试语音支持
      await this.testVoiceSupport()
      
      // 生成总体报告
      this.generateOverallReport()
      
      console.log('[可访问性测试] 测试完成')
      return this.testResults
    } catch (error) {
      console.error('[可访问性测试] 测试过程中出现错误:', error)
      throw error
    }
  }

  // 测试颜色对比度
  async testColorContrast() {
    console.log('[可访问性测试] 测试颜色对比度...')
    
    const elements = document.querySelectorAll('*')
    const contrastIssues = []
    
    elements.forEach(element => {
      const computedStyle = window.getComputedStyle(element)
      const color = computedStyle.color
      const backgroundColor = computedStyle.backgroundColor
      
      if (color && backgroundColor && color !== 'rgba(0, 0, 0, 0)' && backgroundColor !== 'rgba(0, 0, 0, 0)') {
        const contrastRatio = this.calculateContrastRatio(color, backgroundColor)
        
        if (contrastRatio < 4.5) {
          contrastIssues.push({
            element: element.tagName,
            className: element.className,
            contrastRatio: contrastRatio.toFixed(2),
            color,
            backgroundColor,
            severity: contrastRatio < 3 ? 'error' : 'warning'
          })
        }
      }
    })
    
    this.testResults.colorContrast = contrastIssues
    
    if (contrastIssues.length > 0) {
      console.warn(`[可访问性测试] 发现 ${contrastIssues.length} 个颜色对比度问题`)
    }
  }

  // 计算颜色对比度
  calculateContrastRatio(color1, color2) {
    const rgb1 = this.hexToRgb(color1)
    const rgb2 = this.hexToRgb(color2)
    
    if (!rgb1 || !rgb2) return 0
    
    const lum1 = this.getLuminance(rgb1)
    const lum2 = this.getLuminance(rgb2)
    
    const brightest = Math.max(lum1, lum2)
    const darkest = Math.min(lum1, lum2)
    
    return (brightest + 0.05) / (darkest + 0.05)
  }

  // 将颜色转换为RGB
  hexToRgb(color) {
    if (color.startsWith('#')) {
      const hex = color.slice(1)
      return {
        r: parseInt(hex.substr(0, 2), 16),
        g: parseInt(hex.substr(2, 2), 16),
        b: parseInt(hex.substr(4, 2), 16)
      }
    } else if (color.startsWith('rgb')) {
      const matches = color.match(/\d+/g)
      return {
        r: parseInt(matches[0]),
        g: parseInt(matches[1]),
        b: parseInt(matches[2])
      }
    }
    return null
  }

  // 计算亮度
  getLuminance(rgb) {
    const { r, g, b } = rgb
    const [rs, gs, bs] = [r, g, b].map(c => {
      c = c / 255
      return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
    })
    return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs
  }

  // 测试触摸目标大小
  async testTouchTargets() {
    console.log('[可访问性测试] 测试触摸目标大小...')
    
    const touchElements = document.querySelectorAll('button, a, input, [role="button"], .elderly-pressable')
    const touchIssues = []
    
    touchElements.forEach(element => {
      const rect = element.getBoundingClientRect()
      const minSize = 44 // 44px = 88rpx，适老化标准
      
      if (rect.width < minSize || rect.height < minSize) {
        touchIssues.push({
          element: element.tagName,
          className: element.className,
          width: Math.round(rect.width),
          height: Math.round(rect.height),
          minRequired: minSize,
          severity: 'error'
        })
      }
    })
    
    this.testResults.touchTargets = touchIssues
    
    if (touchIssues.length > 0) {
      console.warn(`[可访问性测试] 发现 ${touchIssues.length} 个触摸目标大小问题`)
    }
  }

  // 测试字体大小
  async testFontSizes() {
    console.log('[可访问性测试] 测试字体大小...')
    
    const textElements = document.querySelectorAll('p, span, div, h1, h2, h3, h4, h5, h6, button, a')
    const fontIssues = []
    
    textElements.forEach(element => {
      const computedStyle = window.getComputedStyle(element)
      const fontSize = parseFloat(computedStyle.fontSize)
      const minFontSize = 14 // 14px = 28rpx，适老化标准
      
      if (fontSize < minFontSize) {
        fontIssues.push({
          element: element.tagName,
          className: element.className,
          fontSize: fontSize,
          minRequired: minFontSize,
          text: element.textContent?.substring(0, 50) || '',
          severity: 'warning'
        })
      }
    })
    
    this.testResults.fontSizes = fontIssues
    
    if (fontIssues.length > 0) {
      console.warn(`[可访问性测试] 发现 ${fontIssues.length} 个字体大小问题`)
    }
  }

  // 测试导航可访问性
  async testNavigation() {
    console.log('[可访问性测试] 测试导航可访问性...')
    
    const navigationIssues = []
    
    // 检查是否有跳过链接
    const skipLinks = document.querySelectorAll('a[href="#main"], a[href="#content"]')
    if (skipLinks.length === 0) {
      navigationIssues.push({
        type: 'skip_links',
        message: '缺少跳过链接，影响键盘导航',
        severity: 'warning'
      })
    }
    
    // 检查标题层级
    const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6')
    let lastLevel = 0
    headings.forEach(heading => {
      const level = parseInt(heading.tagName.charAt(1))
      if (level > lastLevel + 1) {
        navigationIssues.push({
          type: 'heading_hierarchy',
          message: `标题层级跳跃: ${heading.tagName}`,
          element: heading,
          severity: 'warning'
        })
      }
      lastLevel = level
    })
    
    // 检查焦点管理
    const focusableElements = document.querySelectorAll('button, a, input, select, textarea, [tabindex]')
    const tabIndexIssues = []
    focusableElements.forEach(element => {
      const tabIndex = element.getAttribute('tabindex')
      if (tabIndex && parseInt(tabIndex) > 0) {
        tabIndexIssues.push(element)
      }
    })
    
    if (tabIndexIssues.length > 0) {
      navigationIssues.push({
        type: 'tab_index',
        message: `发现 ${tabIndexIssues.length} 个正数 tabindex，可能影响键盘导航`,
        severity: 'warning'
      })
    }
    
    this.testResults.navigation = navigationIssues
    
    if (navigationIssues.length > 0) {
      console.warn(`[可访问性测试] 发现 ${navigationIssues.length} 个导航问题`)
    }
  }

  // 测试语音支持
  async testVoiceSupport() {
    console.log('[可访问性测试] 测试语音支持...')
    
    const voiceIssues = []
    
    // 检查语音控制元素
    const voiceElements = document.querySelectorAll('[data-voice-command], .voice-btn, .mic')
    if (voiceElements.length === 0) {
      voiceIssues.push({
        type: 'voice_controls',
        message: '缺少语音控制元素',
        severity: 'warning'
      })
    }
    
    // 检查语音反馈
    const feedbackElements = document.querySelectorAll('[aria-live], .voice-feedback')
    if (feedbackElements.length === 0) {
      voiceIssues.push({
        type: 'voice_feedback',
        message: '缺少语音反馈机制',
        severity: 'warning'
      })
    }
    
    // 检查语音指令帮助
    const helpElements = document.querySelectorAll('.voice-help, [data-voice-help]')
    if (helpElements.length === 0) {
      voiceIssues.push({
        type: 'voice_help',
        message: '缺少语音指令帮助',
        severity: 'info'
      })
    }
    
    this.testResults.voiceSupport = voiceIssues
    
    if (voiceIssues.length > 0) {
      console.warn(`[可访问性测试] 发现 ${voiceIssues.length} 个语音支持问题`)
    }
  }

  // 生成总体报告
  generateOverallReport() {
    const totalIssues = this.testResults.colorContrast.length + 
                       this.testResults.touchTargets.length + 
                       this.testResults.fontSizes.length + 
                       this.testResults.navigation.length + 
                       this.testResults.voiceSupport.length
    
    const errorCount = this.testResults.colorContrast.filter(i => i.severity === 'error').length +
                      this.testResults.touchTargets.filter(i => i.severity === 'error').length +
                      this.testResults.fontSizes.filter(i => i.severity === 'error').length +
                      this.testResults.navigation.filter(i => i.severity === 'error').length +
                      this.testResults.voiceSupport.filter(i => i.severity === 'error').length
    
    const warningCount = this.testResults.colorContrast.filter(i => i.severity === 'warning').length +
                        this.testResults.touchTargets.filter(i => i.severity === 'warning').length +
                        this.testResults.fontSizes.filter(i => i.severity === 'warning').length +
                        this.testResults.navigation.filter(i => i.severity === 'warning').length +
                        this.testResults.voiceSupport.filter(i => i.severity === 'warning').length
    
    let score = 100
    score -= errorCount * 10 // 每个错误扣10分
    score -= warningCount * 5 // 每个警告扣5分
    score = Math.max(0, score) // 最低0分
    
    let grade = 'A'
    if (score < 90) grade = 'B'
    if (score < 80) grade = 'C'
    if (score < 70) grade = 'D'
    if (score < 60) grade = 'F'
    
    this.testResults.overall = {
      score,
      grade,
      totalIssues,
      errorCount,
      warningCount,
      recommendations: this.generateRecommendations()
    }
    
    console.log(`[可访问性测试] 总体评分: ${score}/100 (${grade})`)
    console.log(`[可访问性测试] 问题统计: ${errorCount} 个错误, ${warningCount} 个警告`)
  }

  // 生成优化建议
  generateRecommendations() {
    const recommendations = []
    
    if (this.testResults.colorContrast.length > 0) {
      recommendations.push({
        category: '颜色对比度',
        priority: 'high',
        suggestions: [
          '提高文字与背景的对比度，确保对比度≥4.5:1',
          '使用深色文字配浅色背景，或浅色文字配深色背景',
          '避免使用相似颜色的组合'
        ]
      })
    }
    
    if (this.testResults.touchTargets.length > 0) {
      recommendations.push({
        category: '触摸目标',
        priority: 'high',
        suggestions: [
          '确保所有可点击元素最小尺寸为44px×44px',
          '增加按钮内边距，扩大触摸区域',
          '使用.elderly-pressable类确保适老化标准'
        ]
      })
    }
    
    if (this.testResults.fontSizes.length > 0) {
      recommendations.push({
        category: '字体大小',
        priority: 'medium',
        suggestions: [
          '确保所有文字最小字号为14px (28rpx)',
          '重要信息使用更大字号',
          '使用.elderly-text类确保适老化标准'
        ]
      })
    }
    
    if (this.testResults.navigation.length > 0) {
      recommendations.push({
        category: '导航可访问性',
        priority: 'medium',
        suggestions: [
          '添加跳过链接，方便键盘导航',
          '确保标题层级正确',
          '避免使用正数tabindex'
        ]
      })
    }
    
    if (this.testResults.voiceSupport.length > 0) {
      recommendations.push({
        category: '语音支持',
        priority: 'low',
        suggestions: [
          '添加语音控制元素',
          '提供语音反馈机制',
          '添加语音指令帮助'
        ]
      })
    }
    
    return recommendations
  }

  // 导出测试报告
  exportReport() {
    const report = {
      timestamp: new Date().toISOString(),
      results: this.testResults,
      summary: {
        totalIssues: this.testResults.overall.totalIssues,
        errorCount: this.testResults.overall.errorCount,
        warningCount: this.testResults.overall.warningCount,
        score: this.testResults.overall.score,
        grade: this.testResults.overall.grade
      }
    }
    
    return report
  }

  // 保存测试报告到本地存储
  saveReport() {
    const report = this.exportReport()
    try {
      uni.setStorageSync('accessibility_report', report)
      console.log('[可访问性测试] 报告已保存到本地存储')
    } catch (error) {
      console.error('[可访问性测试] 保存报告失败:', error)
    }
  }

  // 加载历史测试报告
  loadReport() {
    try {
      const report = uni.getStorageSync('accessibility_report')
      if (report) {
        console.log('[可访问性测试] 已加载历史测试报告')
        return report
      }
    } catch (error) {
      console.error('[可访问性测试] 加载报告失败:', error)
    }
    return null
  }
}

// 创建全局实例
const accessibilityTester = new AccessibilityTester()

export { accessibilityTester, AccessibilityTester }
